# -*- coding: utf-8 -*-

'''
@project : SmartHomeVideo
@FileName: mq_rpc
@Author  :linych
@Time    :2021/2/22 15:33
@Desc  :
'''

import asyncio
import random
import uuid
from aio_pika import connect, IncomingMessage, Message
import time

from Core import conf

queue = conf.get('MQ','queue')





class RabbitMQRpcClient:

    loop = None
    connection = None
    url = None

    channl_list = []

    futures ={}


    async def connect(self):

        if RabbitMQRpcClient.loop is None:
            RabbitMQRpcClient.loop = asyncio.get_event_loop()

        if RabbitMQRpcClient.connection is None:

            print('connect....................')
            RabbitMQRpcClient.connection = await connect(
                host=self.url,port=5672, loop=RabbitMQRpcClient.loop,login='test',password='test'
            )

            for i in range(100):
                channel = await self.connection.channel()
                callback_queue = await channel.declare_queue(exclusive=True)
                await callback_queue.consume(self.on_response)

                RabbitMQRpcClient.channl_list.append((channel,callback_queue))




    def on_response(self, message: IncomingMessage):
        print('response ....{}'.format(time.time()))
        future = RabbitMQRpcClient.futures.pop(message.correlation_id)
        future.set_result(message.body)

    async def call(self, correlation_id='',body=''):

        await self.connect()


        channel,callback_queue = random.choice(RabbitMQRpcClient.channl_list)


        if correlation_id is '':
            correlation_id = str(uuid.uuid4())

        future = RabbitMQRpcClient.loop.create_future()

        RabbitMQRpcClient.futures[correlation_id] = future


        s = time.time()
        await channel.default_exchange.publish(
            Message(
                str(body).encode(),
                content_type="text/plain",
                correlation_id=correlation_id,
                reply_to=callback_queue.name,
            ),
            routing_key=queue,
        )
        res = await future

        print('doing.. {}'.format(time.time()-s))

        return res
